local skynet = require "skynet"

local logger = require "logger"
local redis = require "skynet.db.redis"
local bson = require "bson"


local redis_host = skynet.getenv("redis_host") or "127.0.0.1"
local redis_port = skynet.getenv("redis_port") or 6379
local redis_auth = skynet.getenv("redis_auth") or ""
local logs_queue_name = skynet.getenv("redis_logs_queue_name") or "normal_logs"
redis_port = tonumber(redis_port)

local db 

local redis_conf = {
    host = redis_host, 
    port = redis_port, 
    auth = redis_auth,
    db = 0,
}

local task_queue = {}

local function push(key, val)
    local BS_value = bson.encode(val)
    db:rpush(key, BS_value)

    -- logger.debug("logd", "push key", key, ", value", val)
end 

local function persistent(tbl, opt, args)
    assert(opt == "insert" or opt == "update", "log invalid opt : " .. opt) 

    local task = {
        tbl = tbl, 
        opt = opt, 
        args = args, 
    }
    local ok = pcall(push, logs_queue_name, task)
    if not ok then 
        task_queue[#task_queue + 1] = task
    end 
end 

local function process_task_queue()
    while true do 
        if #task_queue > 0 then 
            local task = table.remove(task_queue)

            local ok, result = pcall(push, logs_queue_name, task)
            if not ok then 
                task_queue[#task_queue + 1] = task 
                skynet.sleep(10 * 100) 
            end 
        end 

        skynet.sleep(10 * 100) 
    end 
end 

--------------------------------------------------------------------

local CMD = {} 

function CMD.log_system_activity(uid, event_type, event_value)
    local created = util.get_current_time()
    local tbl = "activity_logs"
    local opt = "insert"
    local args = {
        uid = uid, 
        ev_type = event_type,
        ev_val = event_value,
        created = created,
    }
    persistent(tbl, opt, args)
end 

function CMD.log_exp_change(uid, log_type, value)
    local created = util.get_current_time()
    local tbl = "exp_logs"
    local opt = "insert"
    local args = {
        uid = uid, 
        type = log_type, 
        value = value,
        created = created,
    }
    persistent(tbl, opt, args)
end 


skynet.start(function()
    db = assert(redis.connect(redis_conf), "redis db create failed~")

    skynet.fork(process_task_queue)

    skynet.dispatch("lua", function(_, _, cmd, ...)
        local f = assert(CMD[cmd])
        skynet.ret(skynet.pack(f(...)))
    end)
end)